package com.epfresh.api.http;

import android.os.AsyncTask;
import android.util.Pair;

import com.epfresh.api.http.volley.toolbox.Volley;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;

public class DownloadFile {

	public Object downloadFile(String url, File f,
							   ProgressListener progressListener) {

		InputStream in = null;
		OutputStream out = null;
		HttpURLConnection conn = null;
		int responseCode = -1;
		if (progressListener != null) {
			progressListener.start();
		}
		try {
			URL uri = new URL(url);
			conn = (HttpURLConnection) uri.openConnection();

			conn.setConnectTimeout(30000);
			conn.setReadTimeout(30000);
			conn.setInstanceFollowRedirects(true);
            SSLSocketFactory mSslSocketFactory = Volley.getSocketFactory();
            if ("https".equals(uri.getProtocol()) && mSslSocketFactory != null) {
				((HttpsURLConnection) conn).setSSLSocketFactory(mSslSocketFactory);
				((HttpsURLConnection) conn).setHostnameVerifier( new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
			}
			responseCode = conn.getResponseCode();

			in = conn.getInputStream();
			out = new FileOutputStream(f);

			int total = conn.getContentLength();
			// int total = in.available();
			byte[] buf = new byte[1024];
			int len = 0;
			int progress = 0;
			// 开始下载
			if (progressListener != null) {
				progressListener.progress(progress, total);
			}
			while ((len = in.read(buf, 0, 1024)) != -1) {
				out.write(buf, 0, len);
				if (progressListener != null) {
					progress += len;
					progressListener.progress(progress, total);
				}
			}
			if (progressListener != null) {
				progressListener.finish(f);
			}
			return f;
		} catch (Exception ex) {
			if (progressListener != null) {
				progressListener.error(responseCode, ex.getMessage());
			}
			ex.printStackTrace();

			return new Pair<Integer, String>(responseCode, ex.getMessage());
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (in != null) {
				try {
					in.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (conn != null) {
				conn.disconnect();
				conn = null;
			}
		}
	}

	public AsyncTask<Void, Integer, Object> download(final String url,
			final File f, final ProgressListener progressListener) {
		return new AsyncTask<Void, Integer, Object>() {

			protected void onPreExecute() {
				if (progressListener != null) {
					progressListener.start();
				}
			};
			protected void onProgressUpdate(Integer... values) {
				if (progressListener != null) {
					progressListener.progress(values[0], values[1]);
				}
			};

			@Override
			protected Object doInBackground(Void... params) {
				
				return downloadFile(url, f, new ProgressListener() {

					@Override
					public void start() {

					}

					@Override
					public void progress(int progress, int total) {
						publishProgress(progress, total);

					}

					@Override
					public void finish(File f) {

					}

					@Override
					public void error(int statusCode, String error) {

					}
				});
			}

			protected void onPostExecute(Object result) {
				if (result != null && (result instanceof File)) {
					if (progressListener != null) {
						progressListener.finish(f);
					}
				} else if (result != null && (result instanceof Pair<?, ?>)) {
					if (progressListener != null) {
						progressListener.error(
								((Pair<Integer, String>) result).first,
								((Pair<Integer, String>) result).second);
					}
				}
			};

		}.execute();
	}

	public interface ProgressListener {
		public void progress(int progress, int total);

		public void start();

		public void finish(File f);

		public void error(int statusCode, String error);
	}
}
